package bsh.asm.acessor;

import org.objectweb.asm.MethodVisitor;

import bsh.CompilationState;
import bsh.exception.CompilationFailedException;
import bsh.meta.TypeWrapper;

/**
 * @author takeshi
 */
public interface ObjectAccessor {

    /**
     * @return {@link TypeWrapper}
     */
    TypeWrapper type();

    /**
     * If true, this accessor is read only
     * 
     * @return boolean
     */
    boolean readOnly();

    /**
     * Pushes an object to the stack, generating the necessary bytecode. Updates the {@link CompilationState} accordingly, poping from the
     * stack and pushing to the stack as needed. After this method is called, the stack should be increased by at most 1.
     * 
     * @param visitor {@link MethodVisitor}
     * @param state {@link CompilationState}
     * @throws CompilationFailedException e
     */
    void loadObject(MethodVisitor visitor, CompilationState state) throws CompilationFailedException;

    /**
     * Called to prepare the {@link MethodVisitor} to store a value on this {@link ObjectAccessor}.
     * 
     * @param visitor the {@link MethodVisitor}
     * @param state {@link CompilationState}
     * @throws CompilationFailedException e
     */
    void preStore(MethodVisitor visitor, CompilationState state) throws CompilationFailedException;

    /**
     * @param visitor {@link MethodVisitor}
     * @param state {@link CompilationState}
     * @throws CompilationFailedException e
     */
    void storeObject(MethodVisitor visitor, CompilationState state) throws CompilationFailedException;

}
